#include "head.h"

//插入投诉表
int insert_comp(complaint * c){
    char sql[256];
    char * errmsg;
    //拼接字符串
    sprintf(sql,"insert into comp(person_id,comp_con,reply) values('%d','%s','%s');"
            ,c->person_id,c->complaint_content,c->reply);
    int rc = sqlite3_exec(db,sql,NULL,NULL,&errmsg) ;
    if(rc!=SQLITE_OK ){
        fprintf(stderr,"table comp插入失败：%s\n",errmsg);
        sqlite3_free(errmsg) ;
        return -1;
    }
    printf("comp插入成功！\n");
    return 0;
}
//修改投诉表
//老编号，case选择，投诉结构体指针变量
int update_comp(int old_person_id,int choice,complaint * c) {
    char sql[256];
    char *errmsg;
    //拼接字符串
    //根据选择构建不同的sql语句
    switch(choice) {
        case 1: // 修改业主id
            sprintf(sql, "update comp set person_id = %d where person_id = %d;",
                    c->person_id, old_person_id);
            break;
        case 2: // 修改投诉内容
            sprintf(sql, "update comp set comp_con = '%s' where person_id = %d;",
                    c->complaint_content, old_person_id);
            break;
        case 3: // 修改回复内容
            sprintf(sql, "update comp set reply = '%s' where person_id = %d;",
                    c->reply, old_person_id);
            break;
        default:
            printf("选择无效！\n");
            return -1;
    }
    int rc = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "table comp修改失败：%s\n", errmsg);
        sqlite3_free(errmsg);
        return -1;
    }
    // 检查是否真正修改了记录
    int changes = sqlite3_changes(db);
    //值为0，表示未找到
    if (changes == 0) {
        printf("没找到业主id为'%d'的投诉记录，修改失败！\n", old_person_id);
        return -1;
    }
    printf("修改成功！\n");
    return 0;
}
//删除投诉表
int delete_comp(char *comp_con) {
    char sql[256];
    char *errmsg;
    //拼接字符串
    sprintf(sql, "delete from comp where comp_con = '%s';", comp_con);
    int rc = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "table comp删除失败：%s\n", errmsg);
        sqlite3_free(errmsg);
        return -1;
    }
    // 检查是否删除了记录
    int changes = sqlite3_changes(db);
    //changes为正整数，则成功删除
    if (changes > 0) {
        printf("成功删除投诉内容为 '%s' 的记录\n", comp_con);
    } else {
        printf("没有找到投诉内容为 '%s' 的记录\n", comp_con);
    }
    return changes;//返回删除的记录数
}

//查询投诉表
//用const只读操作，保护数据不会被修改
int query_comp(const char *reply){
  //定义预编译语句句柄
    //执行预编译操作，返回预编译的结果
    const char * sql ="select person_id as 人员编号,comp_con as 投诉原因,reply as 状态 from comp where reply= ? ;";
    sqlite3_stmt * stmt;
    int rc = sqlite3_prepare_v2 (db,sql,-1,&stmt,NULL) ;
    //判断预编译是否成功
    if(rc!=SQLITE_OK ){
        fprintf(stderr,"comp查询预编译出错：%s\n", sqlite3_errmsg(db) );
        return -1;
    }
    //绑定参数
    //句柄，？的位置，参数值，参数长度，参数的销毁方式
    sqlite3_bind_text(stmt,1,reply,-1,SQLITE_TRANSIENT ) ;
    //查列数
    int comp_head_count = sqlite3_column_count(stmt);
    //执行查询sql语句
    int found = 0;
    //判断读取的是否是有效行
    while(sqlite3_step(stmt)==SQLITE_ROW  ){
        //如果找到了，执行if
        if (!found) {
            // 第一次找到数据时输出列名
            comp_head_count = sqlite3_column_count(stmt);
            for (int i = 0; i < comp_head_count; i++) {
                printf("%s|\t", sqlite3_column_name(stmt, i));
            }
            printf("\n");
            found = 1;//确保只输出一次表头
        }
        //获取当前行所指向的列的值
        //sqlite3_column_int，获取当前整型值
        int id = sqlite3_column_int(stmt,0);
        //sqlite3_column_text，获取文本值
        //const表示指向的内容是只读的，防止意外修改
        const char * c = (const char *)sqlite3_column_text(stmt,1);
        const char * r = (const char *)sqlite3_column_text(stmt,2);
        printf("| %d | %s | %s |\n",id,c,r);
    }
    // 如果没有找到记录
    if (!found) {
        printf("没有查到回复内容为 '%s' 的记录\n", reply);
    }
    //释放语句句柄
    sqlite3_finalize(stmt) ;
    return found;//返回操作的结果状态，表示是否找到了记录
}
//关联查询，根据回复内容查询住户信息
int query_comp_person(const char *reply) {
    const char *sql =
            "select "
            "c.person_id as 人员编号, "
            "c.comp_con as 投诉原因, "
            "c.reply as 状态, "
            "r.name as 姓名, "
            "r.phone as 电话, "
            "r.id_card as 身份证号, "
            "r.time as 投诉日期 "
            "from comp c "
            "left join resident r on c.person_id = r.person_id "
            "where c.reply = ?;";
    sqlite3_stmt *stmt;
    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    //判断预编译是否成功
    if (rc != SQLITE_OK) {
        fprintf(stderr, "comp关联查询预编译出错：%s\n", sqlite3_errmsg(db));
        sqlite3_finalize(stmt);
        return -1;
    }
    //绑定参数
    sqlite3_bind_text(stmt, 1, reply, -1, SQLITE_TRANSIENT);
    int found = 0;
    while (sqlite3_step(stmt) == SQLITE_ROW) {
        //found表示找到，！found表示未找到
        if (!found) {
            // 第一次找到数据时输出列名
            int column_count = sqlite3_column_count(stmt);
            for (int i = 0; i < column_count; i++) {
                printf("%s|\t", sqlite3_column_name(stmt, i));
            }
            printf("\n");
            found = 1;//确保表头只输出一次
        }
        //获取当前行所指向列的值
        // 投诉信息
        int id = sqlite3_column_int(stmt, 0);
        const char *comp_con = (const char *) sqlite3_column_text(stmt, 1);
        const char *reply_content = (const char *) sqlite3_column_text(stmt, 2);
        // 住户信息
        const char *name = (const char *) sqlite3_column_text(stmt, 3);
        const char *phone = (const char *) sqlite3_column_text(stmt, 4);
        const char *id_card = (const char *) sqlite3_column_text(stmt, 5);
        const char *time = (const char *) sqlite3_column_text(stmt, 6);

        printf("输出查询结果：| %d | %s | %s | %s | %s | %s | %s |\n",
               id, comp_con, reply_content, name, phone, id_card, time);
    }
    // 如果没有找到记录
    if (!found) {
        printf("没有查到回复内容为 '%s' 的记录\n", reply);
    }
    //释放语句句柄
    sqlite3_finalize(stmt);
    return found;//返回查询操作的结果状态，表示是否找到了记录
}
void main_comp(){
    printf("1.增加投诉信息 2.修改投诉信息 3.删除投诉信息 4.查询投诉信息 5.退出\n");
    int choose_comp;//定义输入选择变量
    //d定义while循环条件
    //e,定义显示菜单
    int d=1,e=0;
    char delete_con[200];//定义删除内容
    complaint  co;//定义投诉结构体变量
    int old_person_id;//定义原来的业主id
    char search_reply[256];//定义查询回复内容
    choose_comp= hcq(choose_comp);
    while(d){
        if(e!=0){
            printf("1.增加投诉信息 2.修改投诉信息 3.删除投诉信息 4.查询投诉信息 5.退出\n");
            choose_comp= hcq(choose_comp);
        }
        e++;//执行某个操作之后，循环输出显示菜单
        switch(choose_comp ){
            case 1:
                //插入功能
                printf("输入业主id: ");
                scanf("%d",&co.person_id);
                printf("输入投诉内容： ");
                scanf("%s",co.complaint_content);
                printf("输入回复内容： ");
                scanf("%s",co.reply);
                insert_comp(&co) ;
                break;
            case 2:
                //修改功能
                printf("输入要修改的业主id: ");
                scanf("%d",&old_person_id);
                char check_sql[100];//定义检查sql语句
                //拼接字符串
                //count(*)表示返回匹配条件的记录数，在这里只返回一个person_id值
                sprintf(check_sql, "select count(*) from comp where person_id = %d;", old_person_id);
                //声明预编译语句句柄
                sqlite3_stmt *check_stmt;
                int rc = sqlite3_prepare_v2(db, check_sql, -1, &check_stmt, NULL);
                if (rc != SQLITE_OK) {
                    fprintf(stderr, "检查失败：%s\n", sqlite3_errmsg(db));
                    //输出错误信息，并跳出当前判断
                    break;
                }
                //判断是否存在
                int exists = 0;
                if (sqlite3_step(check_stmt) == SQLITE_ROW) {
                    //如果是有效行，则将有效行的person_id值这个记录数给exists
                    exists = sqlite3_column_int(check_stmt, 0);
                }
                //释放句柄
                sqlite3_finalize(check_stmt);
                //如果不存在
                if (!exists) {
                    printf("业主id'%d'不存在！\n", old_person_id);
                    break;
                }
                printf("业主id存在，请修改：\n");
                int choice;
                printf("1.修改业主id 2.修改投诉内容 3.修改回复内容\n");
                printf("选择要修改的序号: ");
                scanf("%d", &choice);
                //在测试中发现，当选择其中一个修改的时候，修改成功后，会直接结束，不能循环输出修改菜单，需要再次选择，才能继续修改
                // 根据选择输入相应的数据
                //由于未设置缓冲区问题，当输入的值不是正整数的时候，会出现两次选择无效
                switch(choice) {
                    case 1:
                        printf("输入新业主id: ");
                        scanf("%d", &co.person_id);
                        break;
                    case 2:
                        printf("输入新投诉内容: ");
                        scanf("%s", co.complaint_content);
                        break;
                    case 3:
                        printf("输入新回复内容: ");
                        scanf("%s", co.reply);
                        break;
                    default:
                        printf("选择无效！\n");
                        break;
                }
                update_comp(old_person_id,choice,&co) ;
                break;
            case 3:
                //删除功能
                printf("输入要删除的投诉内容: ");
                //物理删除，当删除投诉内容的时候，回复该投诉内容的内容也会被删除
                scanf("%s",delete_con);
                delete_comp(delete_con) ;
                break;
            case 4:
                //查询功能
                //根据回复内容进行查询
                printf("1.查询回复内容 2.查询回复该内容的个人信息\n");
                printf("请选择查询序号: ");
                int query_choice;
                scanf("%d", &query_choice);
                printf("输入要查询的回复内容: ");
                scanf("%s", search_reply);
                if (query_choice == 1) {
                    // 只查询投诉信息
                    query_comp(search_reply);
                } else if (query_choice == 2) {
                    // 查询投诉信息和关联的住户信息
                    query_comp_person(search_reply);
                } else {
                    printf("选择错误！\n");
                }
                break;
            case 5:
                d=0;
                break;
            default:
                break;
        }
    }
}
